/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * FeedTree.java
 *
 * Created on 31 Οκτ 2010, 12:07:20 μμ
 */
package tools.feeds;

import database.FeedsRecord;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import myComponents.MyMessages;
import myseriesproject.MySeries;
import myseriesproject.actions.FeedsActions;
import tools.MySeriesLogger;

/**
 *
 * @author lordovol
 */
public class FeedTree extends javax.swing.JPanel {

  public static final long serialVersionUID = 34573458937458934L;
  ArrayList<FeedLeaf> model = new ArrayList<FeedLeaf>();
  private DefaultTreeModel treemodel;
  private FeedLeaf selectedLeaf;
  private int selectedRow;
  MySeries m;

  /** Creates new form FeedTree */
  public FeedTree() {
    initComponents();
    tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

  }

  public void setMySeries(MySeries m) {
    this.m = m;
  }

  private void mouseReleased(java.awt.event.MouseEvent evt) {
    DefaultMutableTreeNode node;
    Feed feed;
    FeedPreviewPanel pp;
    MySeriesLogger.logger.log(Level.INFO, "Mouse released on tree");
    if (evt.getButton() == MouseEvent.BUTTON3) {
      Point p = evt.getPoint();
      TreePath selectedPath = tree.getClosestPathForLocation(p.x, p.y);
      if (tree.getPathBounds(selectedPath).contains(p)) {
        tree.setSelectionPath(selectedPath);
        node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        if (node.isLeaf()) {
          setSelectedLeaf((FeedLeaf) node.getUserObject());
          if (getSelectedLeaf().id > 0) {
            MySeriesLogger.logger.log(Level.INFO, "Showing popup menu");
            popup.show(this, evt.getX(), evt.getY());
          }
        }
      }
    }
  }

  public void setCellRenderer(DefaultTreeCellRenderer renderer) {
    tree.setCellRenderer(renderer);
  }

  public TreeCellRenderer getCellRenderer() {
    return tree.getCellRenderer();
  }

  public void populate() {
    populate(selectedRow);
  }

  public void populate(int id) {
    MySeriesLogger.logger.log(Level.INFO, "Populating tree");
    model.clear();
    ArrayList<FeedsRecord> feeds = FeedsRecord.getAll();
    for (Iterator<FeedsRecord> it = feeds.iterator(); it.hasNext();) {
      FeedsRecord f = it.next();
      FeedLeaf l = new FeedLeaf();
      l.id = f.getFeed_ID();
      l.title = f.getTitle();
      l.url = f.getUrl();
      model.add(l);
      MySeriesLogger.logger.log(Level.FINE, "Added leaf {0}", l.title);
    }
    DefaultMutableTreeNode root = createTree(id);
    treemodel = new DefaultTreeModel(root);
    tree.setModel(treemodel);
    tree.setSelectionRow(selectedRow);
  }

  protected DefaultMutableTreeNode createTree(int id) {
    FeedLeaf rootLeaf = new FeedLeaf();
    rootLeaf.id = 0;
    rootLeaf.title = "Rss Feeds";
    rootLeaf.url = "";
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(rootLeaf);
    int i = 0;
    MySeriesLogger.logger.log(Level.INFO, "Creating tree with {0} leaves", model.size());
    for (Iterator<FeedLeaf> it = model.iterator(); it.hasNext();) {
      FeedLeaf feedLeaf = it.next();
      DefaultMutableTreeNode listNode = new DefaultMutableTreeNode(feedLeaf);
      root.add(listNode);
      i++;
      if (id == feedLeaf.id) {
        selectedRow = i;
      }

    }
    return root;
  }

  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    popup = new javax.swing.JPopupMenu();
    edit = new javax.swing.JMenuItem();
    delete = new javax.swing.JMenuItem();
    update = new javax.swing.JMenuItem();
    FeedScrollPane = new javax.swing.JScrollPane();
    tree = new javax.swing.JTree();

    edit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/rss_edit.png"))); // NOI18N
    edit.setText("Edit Feed");
    edit.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        editActionPerformed(evt);
      }
    });
    popup.add(edit);

    delete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/rss_delete.png"))); // NOI18N
    delete.setText("Delete Feed");
    delete.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        deleteActionPerformed(evt);
      }
    });
    popup.add(delete);

    update.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/rss_refresh.png"))); // NOI18N
    update.setText("Update Feed");
    update.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        updateActionPerformed(evt);
      }
    });
    popup.add(update);

    tree.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 1));
    tree.setFont(tree.getFont().deriveFont(tree.getFont().getStyle() | java.awt.Font.BOLD, tree.getFont().getSize()-1));
    tree.setModel(treemodel);
    tree.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseReleased(java.awt.event.MouseEvent evt) {
        treeMouseReleased(evt);
      }
    });
    tree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
      public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
        treeValueChanged(evt);
      }
    });
    FeedScrollPane.setViewportView(tree);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(FeedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(FeedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
    );
  }// </editor-fold>//GEN-END:initComponents

  private void deleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteActionPerformed
    if (MyMessages.confirm("Delete Feed", "Do you really want to delete this feed", true) == JOptionPane.YES_OPTION) {
      MySeriesLogger.logger.log(Level.INFO, "Deleting feed");
      FeedsRecord feed;
      try {
        feed = FeedsRecord.queryOne(FeedsRecord.C_FEED_ID + "=?",
            new String[]{String.valueOf(getSelectedLeaf().id)}, null);
        if (feed.delete()) {
          MySeriesLogger.logger.log(Level.FINE, "Feed deleted");
          populate(-1);
        }else {
          MyMessages.error("Delete feed", "Could not delete the feed", true);
        }
      } catch (SQLException ex) {
        MySeriesLogger.logger.log(Level.SEVERE, null, ex);
        MyMessages.error("Delete feed", "Could not delete the feed", true);
      }

    }

    popup.setVisible(false);
  }//GEN-LAST:event_deleteActionPerformed

  private void treeMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_treeMouseReleased
    mouseReleased(evt);
  }//GEN-LAST:event_treeMouseReleased

  private void editActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editActionPerformed
    FeedsActions.addFeedPanel(getSelectedLeaf().id, m);
  }//GEN-LAST:event_editActionPerformed

  private void updateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateActionPerformed
    MySeriesLogger.logger.log(Level.INFO, "Updating feed");
    try{
    FeedsRecord feed = FeedsRecord.queryOne(FeedsRecord.C_FEED_ID + "=?",
            new String[]{String.valueOf(getSelectedLeaf().id)}, null);
    FeedUpdater fu = new FeedUpdater(this, feed, m, true);
    Thread t = new Thread(fu);
    t.start();
    }catch(SQLException ex){
      
    }
  }//GEN-LAST:event_updateActionPerformed

  private void treeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_treeValueChanged
    if (evt.getNewLeadSelectionPath() != null) {
      MySeriesLogger.logger.log(Level.INFO, "Tree value changed");
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) evt.getNewLeadSelectionPath().getLastPathComponent();
      if (node.isLeaf()) {
        if (node.getUserObject() instanceof FeedLeaf) {
          FeedLeaf leaf = (FeedLeaf) node.getUserObject();
          //System.out.println("changing to leaf " + leaf);
          if (leaf.id > 0) {
            MySeriesLogger.logger.log(Level.INFO, "Selected leaf {0}", leaf.title);
            selectedRow = tree.getSelectionRows()[0];
            try{
            FeedsRecord feedsRecord = FeedsRecord.queryOne(FeedsRecord.C_FEED_ID + "=?",
            new String[]{String.valueOf(leaf.id)}, null);
            FeedReader fr = new FeedReader(this, feedsRecord, m);
            Feed feed = fr.getFeed();
            FeedPreviewPanel pp = m.feedPreviewPanel;
            pp.setFeed(feed);
            }catch (SQLException ex){
              MySeriesLogger.logger.log(Level.SEVERE, "Could not change feed");
            }
          }
        } else {
          FeedPreviewPanel pp = m.feedPreviewPanel;
          pp.removeFeeds();
        }
      }
    } else {
    }
  }//GEN-LAST:event_treeValueChanged
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JScrollPane FeedScrollPane;
  private javax.swing.JMenuItem delete;
  private javax.swing.JMenuItem edit;
  private javax.swing.JPopupMenu popup;
  public javax.swing.JTree tree;
  private javax.swing.JMenuItem update;
  // End of variables declaration//GEN-END:variables

  public void updateFeeds(ArrayList<FeedsRecord> feeds, boolean readFeeds) {
    MySeriesLogger.logger.log(Level.INFO, "Updating all feeds");
    FeedUpdater fu = new FeedUpdater(this, feeds, readFeeds, m);
    Thread t = new Thread(fu);
    t.start();
  }

  /**
   * @return the selectedLeaf
   */
  public FeedLeaf getSelectedLeaf() {
    return selectedLeaf;
  }

  /**
   * @param selectedLeaf the selectedLeaf to set
   */
  public void setSelectedLeaf(FeedLeaf selectedLeaf) {
    this.selectedLeaf = selectedLeaf;
  }
}
